package dync.rtmpc_demo.utils;

import android.content.Context;
import android.view.View;
import android.widget.ImageView;
import android.widget.RelativeLayout;

import org.anyrtc.rtmpc_hybrid.RTMPCViewHelper;
import org.webrtc.EglBase;
import org.webrtc.PercentFrameLayout;
import org.webrtc.RendererCommon;
import org.webrtc.SurfaceViewRenderer;
import org.webrtc.VideoRenderer;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import dync.rtmpc_demo.R;


/**
 * Created by Eric on 2016/7/26.
 */
public class RTMPCVideoView implements RTMPCViewHelper {
    private static final int SUB_X = 75;
    private static final int SUB_Y = 0;
    public static final int SUB_WIDTH = 25;
    private static final int SUB_HEIGHT = 24;

    private BtnVideoCloseEvent mVideoCloseEvent;
    private boolean isHost;

    public interface BtnVideoCloseEvent {
        void CloseVideoRender(View view, String strPeerId);

        void OnSwitchCamera(View view);
    }


    /**
     * 设置连线关闭按钮事件
     *
     * @param btnVideoCloseEvent
     */
    public void setBtnCloseEvent(BtnVideoCloseEvent btnVideoCloseEvent) {
        this.mVideoCloseEvent = btnVideoCloseEvent;
    }

    protected static class VideoView {
        public String strPeerId;
        public int index;
        public int x;
        public int y;
        public int w;
        public int h;
        public PercentFrameLayout mLayout = null;
        public SurfaceViewRenderer mView = null;
        public VideoRenderer mRenderer = null;
        public ImageView btnClose = null;
        private RelativeLayout layoutCamera = null;

        public VideoView(String strPeerId, Context ctx, EglBase eglBase, int index, int x, int y, int w, int h) {
            this.strPeerId = strPeerId;
            this.index = index;
            this.x = x;
            this.y = y;
            this.w = w;
            this.h = h;

            mLayout = new PercentFrameLayout(ctx);
            mLayout.setLayoutParams(new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.MATCH_PARENT));
            View view = View.inflate(ctx, R.layout.layout_top_right, null);

            mView = (SurfaceViewRenderer) view.findViewById(R.id.suface_view);
            btnClose = (ImageView) view.findViewById(R.id.img_close_render);
            layoutCamera = (RelativeLayout) view.findViewById(R.id.layout_camera);
            mView.init(eglBase.getEglBaseContext(), null);
            mView.setLayoutParams(new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.MATCH_PARENT));
            mLayout.addView(view);
        }

        public Boolean Fullscreen() {
            return w == 100 || h == 100;
        }

        public void close() {
            mLayout.removeView(mView);
            mView.release();
            mView = null;
            mRenderer = null;
        }
    }

    private boolean mAutoLayout;
    private EglBase mRootEglBase;
    private RelativeLayout mVideoView;
    private VideoView mLocalRender;
    private HashMap<String, VideoView> mRemoteRenders;

    public RTMPCVideoView(RelativeLayout videoView, EglBase eglBase, boolean isHost) {
        mAutoLayout = false;
        mVideoView = videoView;
        mRootEglBase = eglBase;
        mLocalRender = null;
        mRemoteRenders = new HashMap<>();
        this.isHost = isHost;
    }

    public int GetVideoRenderSize() {
        int size = mRemoteRenders.size();
        if (mLocalRender != null) {
            size += 1;
        }
        return size;
    }

    private void SwitchViewPosition(VideoView view1, VideoView view2) {
        int index, x, y, w, h;
        index = view1.index;
        x = view1.x;
        y = view1.y;
        w = view1.w;
        h = view1.h;
        view1.index = view2.index;
        view1.x = view2.x;
        view1.y = view2.y;
        view1.w = view2.w;
        view1.h = view2.h;

        view2.index = index;
        view2.x = x;
        view2.y = y;
        view2.w = w;
        view2.h = h;

        view1.mLayout.setPosition(view1.x, view1.y, view1.w, view1.h);
        view2.mLayout.setPosition(view2.x, view2.y, view2.w, view2.h);
        mVideoView.updateViewLayout(view1.mLayout, new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.MATCH_PARENT));
        mVideoView.updateViewLayout(view2.mLayout, new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.MATCH_PARENT));
    }

    public void BubbleSortSubView(VideoView view) {
        if (mLocalRender != null && view.index + 1 == mLocalRender.index) {
            SwitchViewPosition(mLocalRender, view);
        } else {
            Iterator<Map.Entry<String, VideoView>> iter = mRemoteRenders.entrySet().iterator();
            while (iter.hasNext()) {
                Map.Entry<String, VideoView> entry = iter.next();
                VideoView render = entry.getValue();
                if (view.index + 1 == render.index) {
                    SwitchViewPosition(render, view);
                    break;
                }
            }
        }
        if (view.index < mRemoteRenders.size()) {
            BubbleSortSubView(view);
        }
    }

    /**
     * Implements for AnyRTCViewEvents.
     */
    @Override
    public VideoRenderer OnRtcOpenLocalRender(RendererCommon.ScalingType scalingtype) {
        int size = GetVideoRenderSize();

        if (size == 0) {
            mLocalRender = new VideoView("localRender", mVideoView.getContext(), mRootEglBase, 0, 0, 0, 100, 100);
        } else {
            mLocalRender = new VideoView("localRender", mVideoView.getContext(), mRootEglBase, size, SUB_X, (100 - size * (SUB_HEIGHT + SUB_Y)), SUB_WIDTH, SUB_HEIGHT);
            mLocalRender.mView.setZOrderMediaOverlay(true);
        }

        mVideoView.addView(mLocalRender.mLayout);

        mLocalRender.mLayout.setPosition(mLocalRender.x, mLocalRender.y, mLocalRender.w, mLocalRender.h);
        mLocalRender.mView.setScalingType(scalingtype);
        mLocalRender.mRenderer = new VideoRenderer(mLocalRender.mView);
        return mLocalRender.mRenderer;
    }

    @Override
    public void OnRtcRemoveLocalRender() {
        if (mLocalRender != null) {
            mLocalRender.close();
            mLocalRender.mRenderer = null;

            mVideoView.removeView(mLocalRender.mLayout);
            mLocalRender = null;
        }
    }

    @Override
    public VideoRenderer OnRtcOpenRemoteRender(final String strRtcPeerId, RendererCommon.ScalingType scalingtype) {
        VideoView remoteRender = mRemoteRenders.get(strRtcPeerId);
        if (remoteRender == null) {
            int size = GetVideoRenderSize();
            if (size == 0) {
                remoteRender = new VideoView(strRtcPeerId, mVideoView.getContext(), mRootEglBase, 0, 0, 0, 100, 100);
            } else {
                remoteRender = new VideoView(strRtcPeerId, mVideoView.getContext(), mRootEglBase, size, SUB_X, (100 - size * (SUB_HEIGHT + SUB_Y)), SUB_WIDTH, SUB_HEIGHT);
                remoteRender.mView.setZOrderMediaOverlay(true);
                RelativeLayout parent = (RelativeLayout) remoteRender.mView.getParent();
                parent.setPadding(3,3,3,3);
                parent.setBackgroundResource(R.drawable.shape_video_bgl);
                //ViewGroup.LayoutParams layoutParams = (ViewGroup.LayoutParams) parent;
            }

            mVideoView.addView(remoteRender.mLayout);

            remoteRender.mLayout.setPosition(remoteRender.x, remoteRender.y, remoteRender.w, remoteRender.h);
            remoteRender.mView.setScalingType(scalingtype);
            remoteRender.mRenderer = new VideoRenderer(remoteRender.mView);

            mRemoteRenders.put(strRtcPeerId, remoteRender);
            if (isHost || (!isHost && strRtcPeerId.equals("LocalCameraRender"))) {
                remoteRender.btnClose.setVisibility(View.VISIBLE);
                if (!isHost) {
                    remoteRender.layoutCamera.setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View v) {
                            if (null != mVideoCloseEvent) {
                                mVideoCloseEvent.OnSwitchCamera(v);
                            }
                        }
                    });
                }
                remoteRender.btnClose.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        if (null != mVideoCloseEvent) {
                            mVideoCloseEvent.CloseVideoRender(v, strRtcPeerId);
                        }
                    }
                });
            }
        }
        return remoteRender.mRenderer;
    }

    @Override
    public void OnRtcRemoveRemoteRender(String peerId) {
        VideoView remoteRender = mRemoteRenders.get(peerId);
        if (remoteRender != null) {
            if (mRemoteRenders.size() > 1 && remoteRender.index <= mRemoteRenders.size()) {
                BubbleSortSubView(remoteRender);
            }
            remoteRender.close();
            mVideoView.removeView(remoteRender.mLayout);
            mRemoteRenders.remove(peerId);
        }
    }
}
